unit joystick;

interface

const
	stickFailPoint=$3FFF;

var
	stickPort:word;

function joystickPosition(stick:byte):word;
function joystickButton(button:byte):boolean;
procedure joystickDebounce;

implementation

const
	defaultStickPort=$201;


function joystickPosition(stick:byte):word; assembler;
asm
  mov  ah,1
  mov  cl,stick
  and  cl,$03
  shl  ah,cl
  mov  cx,$3FFF
  mov  dx,stickPort
  mov  al,$FF
  cli
  out  dx,al
@testLoop:
	in   al,dx
	test al,ah
	jz   @done
	loop @testLoop
@done:
	sti
	or   cx,$C000
	not  cx
	mov  ax,cx
end;

function joystickButton(button:byte):boolean; assembler;
asm
	mov  ah,$10
	mov  cl,button
	and  cl,$03
	shl  ah,cl
	mov  dx,stickPort
	in   al,dx
	test al,ah
	{ just grabbing the flags with and is WAY quicker than a jxx }
	lahf
	and  ah,$40
	mov  al,ah
end;

procedure joystickDebounce;
begin
	repeat until not(
		joystickButton(0) or
		joystickButton(1) or
		joystickButton(2) or
		joystickButton(3)
	);
end;

begin
	{
		"stickPort" exists just so that if we do decide we want
		to use a non-standard port from a program, we can do so
		without editing this unit.
	}
	stickPort:=defaultStickPort;
end.